package com.scs.application.modules.base.controller;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.dto.ExcelImportField;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.exception.ValidException;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.query.QueryContextHolder;
import com.scs.application.core.query.QueryGenerator;
import com.scs.application.core.threadLock.ThreadLock;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilCommon;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.base.dto.MatrApplyDemandDTO;
import com.scs.application.modules.base.entity.Matr;
import com.scs.application.modules.base.entity.Mfg;
import com.scs.application.modules.base.enums.ExcelImportBaseDataConfig;
import com.scs.application.modules.base.service.MatrService;
import com.scs.application.modules.base.service.MfgService;
import com.scs.application.modules.sys.model.PageResult;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.wm.dto.StockGroupWarehouseMatrDTO;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.entity.WorkOrderItem;
import com.scs.application.modules.wm.mapper.WorkOrderItemMapper;
import com.scs.application.modules.wm.service.StockService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 耗材信息 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/base/matr")
public class MatrController extends CrudController<MatrService, Matr> {
    @Autowired
    StockService stockService;
    @Autowired
    MfgService mfgService;
    @Autowired
    private WorkOrderItemMapper workOrderItemMapper;

    /**
     * 查询耗材信息（含耗材库存总量）
     *
     * @return
     */
    @GetMapping("/listWithStock")
    public RestResult listWithStock(@RequestParam Map<String, String> reqData) {
        QueryContext queryContext = QueryContextHolder.currentContext();
        if (StringUtils.trimToNull((String) reqData.get("keyword")) != null)
            queryContext.getParams().put("keyword", reqData.get("keyword"));


        List<Map> matrs = this.service.listWithStock(queryContext);
        return RestResult.ok("查询成功", matrs);
    }

    /**
     * 查询耗材信息 科室需求
     *
     * @return
     */
    @GetMapping("/listWithDemand")
    public RestResult listWithDemand() {
        QueryContext queryContext = QueryContextHolder.currentContext();

        List<Map> matrs = this.service.listWithDemand(queryContext);
        return RestResult.ok("查询成功", matrs);
    }

    @PostMapping("/uploadPicture")
    public RestResult uploadPicture(@RequestParam("file") MultipartFile file, @RequestParam("matrId") String matrId) {
        return RestResult.ok("上传文件成功!", service.uploadPicture(file, matrId));
    }

    @Override
    public void fillDataForWeb(Matr entity) {
        Boolean flagDisabledSpEdit = StringUtils.isNotBlank(entity.getMscmCode())
                || workOrderItemMapper.selectCount(Wrappers.<WorkOrderItem>query().eq("matr_id", entity.getId())) > 0
                ;
        entity.setFlagDisabledSpEdit(flagDisabledSpEdit);
    }

    // 校验属性设置
    @Override
    public void setBatchCheck(String idValue,String field,Object valueNew) {
        if ("supplierId".equals(field)) {
            Matr matrDb = service.getById(idValue);
            BusinessException.throwValidFailIf(matrDb == null, "商品不存在,请刷新重试");
            BusinessException.throwValidFailIf(StringUtils.isNotBlank(matrDb.getMscmCode()), "商品[%s]已做了外网对照，不可修改供应商",matrDb.getName());
            BusinessException.throwValidFailIf(workOrderItemMapper.selectCount(Wrappers.<WorkOrderItem>query().eq("matr_id", matrDb.getId())) > 0
                    , "商品[%s]已做了出入库，不可修改供应商",matrDb.getName()
            );
        }
    }

    /**
     * 添加/更新数据
     */
    @PostMapping("/save")
    @Override
    public RestResult saveItem(@Valid @RequestBody Matr entity) {
        if (entity.isNewRecord()) {
            if (StringUtils.isBlank(entity.getHrpName())) {
                entity.setHrpName(entity.getName());
            }
            if (StringUtils.isBlank(entity.getHrpSpec())) {
                entity.setHrpSpec(entity.getSpec());
            }

            if (StringUtils.isBlank(entity.getHrpUnit())) {
                entity.setHrpUnit(entity.getSkuUnit());
            }
            Mfg mfg = mfgService.getById(entity.getMfgId());
            if (mfg != null) {
                if (StringUtils.isBlank(entity.getHrpMfg())) {
                    entity.setHrpMfg(mfg.getName());
                }
                if (StringUtils.isBlank(entity.getHrpMfgCode())) {
                    entity.setHrpMfgCode(mfg.getHrpCode());
                }
            }

        } else{
            Matr matrDb = service.getById(entity.getId());
            if (
                    (
                            ObjectUtil.isAllNotEmpty(matrDb.getSkuPrice(),entity.getSkuPrice())
                            && !NumberUtil.equals(matrDb.getSkuPrice(), entity.getSkuPrice())
                    )
                    &&
                    (
                            ObjectUtil.isAllNotEmpty(matrDb.getHisPrice(),entity.getHisPrice())
                            && !NumberUtil.equals(matrDb.getHisPrice(), entity.getHisPrice())
                    )
                    &&
                    workOrderItemMapper.selectCount(Wrappers.<WorkOrderItem>query().eq("matr_id", entity.getId())) > 0
            ) {
                BusinessException.throwValidFail("该商品已存在出入库记录，单品价格、his价格请到调价模块进行调价");
            }

            if (
                    !matrDb.getSupplierName().equals(entity.getSupplierName())
            ) {
                if (StringUtils.isNotBlank(matrDb.getMscmCode())) {
                    return RestResult.error("商品已做了外网对照，不可修改供应商");
                }
                if (workOrderItemMapper.selectCount(Wrappers.<WorkOrderItem>query().eq("matr_id", entity.getId())) > 0) {
                    return RestResult.error("商品已做了出入库，不可修改供应商");
                }

            }

        }
        boolean isOk = service.saveOrUpdate(entity);
        if (!isOk) {
            return RestResult.error("数据保存失败");
        }
        return RestResult.ok("数据保存成功", entity);
    }


    /**
     * 删除数据
     */
    @DeleteMapping("/delete")
    public RestResult deleteItems(@RequestBody Map<String, Object> para) {
        List<Serializable> ids = (List<Serializable>) para.get("ids");

        List<String> matrIds = service.list(Wrappers.<Matr>query().in("id", ids)).stream().map(Matr::getId).collect(Collectors.toList());
        if (matrIds != null && matrIds.size() > 0 && stockService.count(Wrappers.<Stock>query().in("matr_id", matrIds)) > 0) {
            throw new BusinessException("该耗材已有库存记录，不允许删除");
        }

        //若只修改采购属性，禁用属性，请领属性则不提示
        if (matrIds != null && matrIds.size() > 0  && workOrderItemMapper.selectCount(Wrappers.<WorkOrderItem>query().in("matr_id", matrIds)) > 0) {
            throw new BusinessException("该耗材已有出入库记录，不允许删除");
        }

        Boolean isOk = service.removeCascadeByIds(ids);
        if (!isOk) {
            return RestResult.error("数据删除失败");
        }
        return RestResult.ok("数据删除成功");
    }

    /**
     * 业务选择时候使用
     */
    @GetMapping("/pageForSelect")
    public PageResult pageForSelect() {
        QueryContext queryContext = QueryContextHolder.currentContext();
        queryContext.getWrapper().eq("his_disabled", 0);
        queryContext.getWrapper().eq("flag_disabled", 0);
        IPage pageResult = service.page(queryContext);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }


    /**
     * 获取数据列表
     */
    @RequestMapping("/pageWithStock")
    public PageResult pageWithStock(@RequestBody Map<String, Object> reqData, HttpServletRequest request) {
        QueryContext queryContext = new QueryContext();
        Map<String, Object> userParam = null;
        //固定参数8
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }

        queryContext.setWrapper(QueryGenerator.initQueryWrapper((String) reqData.get("queryString"), (String) reqData.get("orderString")));

        Page page = new Page();
        long currentPage = Long.parseLong(UtilCommon.getStr(reqData.get("currentPage") + "", "1"));
        long rowsPerPage = Long.parseLong(UtilCommon.getStr(reqData.get("rowsPerPage") + "", "10"));
        page.setCurrent(currentPage).setSize(rowsPerPage);
        queryContext.setPage(page);

        IPage pageResult = service.pageWithStock(queryContext, userParam);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    /**
     * 获取数据列表
     */
    @RequestMapping("/pageWithStockMatr")
    public PageResult pageWithStockMatr(@RequestBody Map<String, Object> reqData, HttpServletRequest request) {
        QueryContext queryContext = new QueryContext();
        Map<String, Object> userParam = null;
        //固定参数8
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }

        queryContext.setWrapper(QueryGenerator.initQueryWrapper((String) reqData.get("queryString"), (String) reqData.get("orderString")));

        Page page = new Page();
        long currentPage = Long.parseLong(reqData.get("currentPage") == null ? "1" : reqData.get("currentPage").toString());
        long rowsPerPage = Long.parseLong(reqData.get("rowsPerPage") == null ? "1" : reqData.get("rowsPerPage").toString());
        page.setCurrent(currentPage).setSize(rowsPerPage);
        queryContext.setPage(page);

        IPage pageResult = service.pageInStock(queryContext, userParam);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    @RequestMapping("/pageWithStockForReport")
    public PageResult pageForReportMatr(@RequestBody Map<String, Object> reqData, HttpServletRequest request) {
        QueryContext queryContext = new QueryContext();
        Map<String, Object> userParam = null;
        //固定参数8
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }

        queryContext.setWrapper(QueryGenerator.initQueryWrapper((String) reqData.get("queryString"), (String) reqData.get("orderString")));

        Page page = new Page();
        long currentPage = Long.parseLong(UtilCommon.getStr(reqData.get("currentPage") + "", "1"));
        long rowsPerPage = Long.parseLong(UtilCommon.getStr(reqData.get("rowsPerPage") + "", "10"));
        page.setCurrent(currentPage).setSize(rowsPerPage);
        queryContext.setPage(page);

        IPage pageResult = service.pageForReportMatr(queryContext, userParam);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }


    /**
     * 根据mscm_code查询耗材
     *
     * @param para
     */
    @PostMapping("/getMatrByMscmCode")
    public RestResult getMatrByMscmCode(@RequestBody Map para) {
        String mscmCode = para.get("mscmCode").toString();
        String matrId = service.getMatrByMscmCode(mscmCode);
        return RestResult.ok("ok", matrId);
    }


    /**
     * 根据mscm_code查询耗材
     *
     * @param para
     */
    @PostMapping("/getOnceMatrMscm")
    public RestResult matrOnceToMscm(@RequestBody List<String> idList) {
        return service.matrOnceToMscm(idList);
    }

    /**
     * 根据mscm_code查询耗材
     *
     * @param para
     */
    @PostMapping("/copyMatr")
    public RestResult copyMatr(@RequestBody Map para) {
        String id = para.get("id").toString();
        return service.copyMatr(id);
    }

    @GetMapping("/pageUsing")
    public PageResult pageHis(@RequestParam Map<String, Object> reqData) {
        QueryContext queryContext = QueryContextHolder.currentContext();
        Map<String, Object> userParam = null;
        //固定参数
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
            queryContext.setParams(userParam);
        }
        IPage pageResult = service.pageUsing(queryContext);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    /**
     * 获取数据列表 科室请领需求
     */
    @RequestMapping("/pageWithStockForApplyDemand")
    public PageResult pageWithStockForApplyDemand(@RequestBody Map<String, Object> reqData, HttpServletRequest request) {
        QueryContext queryContext = new QueryContext();
        Map<String, Object> userParam = null;
        //固定参数8
        String warehouseIdStock = null;
        String busType;
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
            warehouseIdStock = String.valueOf(userParam.get("warehouseIdStock"));
            busType = String.valueOf(userParam.get("busType"));
        } else {
            busType = "";
        }
        String orderString = UtilCommon.getStr(reqData.get("orderString")+"", "");
        orderString = orderString.replace("canUseCountMsg", "canUseCount"); //可用库存数量是文字描述的，无法进行排序，所以改成canUseCount
        queryContext.setWrapper(QueryGenerator.initQueryWrapper((String) reqData.get("queryString"), orderString));

        Page page = new Page();
        long currentPage = Long.parseLong(UtilCommon.getStr("" + reqData.get("currentPage"), "1"));
        long rowsPerPage = Long.parseLong(UtilCommon.getStr("" + reqData.get("rowsPerPage"), "10"));
        page.setCurrent(currentPage).setSize(rowsPerPage);
        queryContext.setPage(page);

        Page<MatrApplyDemandDTO> pageResult = service.pageWithStockForApplyDemand(queryContext, userParam);

        //可用库存
        if (pageResult.getRecords() != null && pageResult.getRecords().size() > 0) {
            List<String> matrIdList = pageResult.getRecords().stream().map(MatrApplyDemandDTO::getMatrId).distinct().collect(Collectors.toList());
            List<StockGroupWarehouseMatrDTO> stockGroupWarehouseMatrDTOS = stockService.getListGroupByMatr(
                    Wrappers.<Stock>query().in("matr_id", matrIdList).eq(StringUtils.isNotBlank(warehouseIdStock), "warehouse_id", warehouseIdStock)
            );
            if (stockGroupWarehouseMatrDTOS != null && stockGroupWarehouseMatrDTOS.size() > 0) {
                List<String> msgArr = new ArrayList<String>();
                for (MatrApplyDemandDTO matrApplyDemandDTO : pageResult.getRecords()) {
                    List<StockGroupWarehouseMatrDTO> findList = stockGroupWarehouseMatrDTOS.stream()
                            .filter(stockGroupWarehouseMatrDTO -> matrApplyDemandDTO.getMatrId().equals(stockGroupWarehouseMatrDTO.getMatrId()))
                            .collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(findList)) {
                        msgArr.clear();
                        findList.forEach(stockGroupWarehouseMatrDTO -> {
                            if ("dept_apply".equals(busType)) {
                                msgArr.add(UtilNum.trimZero(stockGroupWarehouseMatrDTO.getSkuQtyUseApply()) + matrApplyDemandDTO.getSkuUnit());
                            } else{
                                msgArr.add(UtilNum.trimZero(stockGroupWarehouseMatrDTO.getSkuQtyUse()) + matrApplyDemandDTO.getSkuUnit());
                            }
                            matrApplyDemandDTO.setCanUseCount(UtilNum.getDouble(matrApplyDemandDTO.getCanUseCount()) + UtilNum.getDouble(stockGroupWarehouseMatrDTO.getSkuQtyUse()));
                        });
                        matrApplyDemandDTO.setCanUseCountMsg(StringUtils.join(msgArr, "\n"));
                    } else {
                        matrApplyDemandDTO.setCanUseCountMsg("无库存");
                    }
                }
            } else {
                for (MatrApplyDemandDTO matrApplyDemandDTO : pageResult.getRecords()) {
                    matrApplyDemandDTO.setCanUseCountMsg("无库存");
                }
            }
        }
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }

    @PostMapping("/updateTemporaryPurchase")
    public void updateTemporaryPurchase(@RequestBody @Valid List<String> list) {
        service.updateTemporaryPurchase(list);
    }

    //获取耗材所属仓库列表
    @GetMapping("/getMatrWarehouseList")
    public RestResult<List> getMatrWarehouseList() {
        return RestResult.ok("查询成功", service.getMatrWarehouseList());
    }

    /**
     * 获取数据列表
     */
    @GetMapping("/pageError")
    public PageResult pageError() {
        QueryContext queryContext = QueryContextHolder.currentContext();

        queryContext.getWrapper().apply(" ((base_type != '"+GlobalConsts.MATR_BASE_TYPE_LOM+"' and (flag_disabled_sp = 1  or flag_disabled = 1 or his_disabled =1  or hrp_finance_disabled =1   or hrp_disabled =1 )) " +
                " or (base_type = '"+GlobalConsts.MATR_BASE_TYPE_LOM+"' and (flag_disabled = 1 )))");
        IPage<Matr> pageResult = (IPage<Matr>) service.page(queryContext);
        if (pageResult.getRecords() != null && pageResult.getRecords().size() > 0) {
            List<String> errmsgList = new ArrayList<>();
            for(Matr matr: pageResult.getRecords()) {
                errmsgList = new ArrayList<>();

                if (matr.getFlagDisabled() != null && matr.getFlagDisabled()) {
                    errmsgList.add("商品禁用");
                }
                if (matr.getHisDisabled() != null && matr.getHisDisabled()) {
                    errmsgList.add("HIS禁用");
                }
                if (matr.getHrpDisabled() != null && matr.getHrpDisabled()) {
                    errmsgList.add("HRP禁用");
                }
                if (matr.getHrpFinanceDisabled() != null && matr.getHrpFinanceDisabled()) {
                    errmsgList.add("财务禁用");
                }

                if (!GlobalConsts.MATR_BASE_TYPE_LOM.equals(matr.getBaseType())) {
                    if (matr.getFlagDisabledSp() != null && matr.getFlagDisabledSp()) {
                        errmsgList.add("供应商禁用");
                    }
                    if (matr.getMscmDisabled() != null && matr.getMscmDisabled()) {
                        errmsgList.add("外网禁用");
                    }
                    if (StringUtils.isBlank(matr.getMscmCode())) {
                        errmsgList.add("外网未同步");
                    }
                    if (StringUtils.isBlank(matr.getSupplierId()) || "-1".equals(matr.getSupplierId())) {
                        errmsgList.add("无供应商");
                    }
                    if (matr.getSkuPrice() != null && matr.getHisPrice() !=null && !NumberUtil.equals(matr.getSkuPrice(),matr.getHisPrice())) {
                        errmsgList.add("单品价格与HIS价格不一致");
                    }
                }

                matr.setMatrErrMsg(StringUtils.join(errmsgList,","));
            }
        }
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }


    /**
     * @description: 拆分商品 下载导入模板
     **/
    @GetMapping("/excelDownloadTempForDataSplit")
    public void excelDownloadTempForDataSplit(HttpServletResponse response, @RequestParam Map<String, String> reqData) {
        service.excelDownloadTemp(response,reqData, ExcelImportBaseDataConfig.getMatrDataSplit());
    }

    /**
     * @description: 拆分商品 导入数据
     **/
    @RequestMapping(value = "/excelImportForDataSplit", method = RequestMethod.POST)
    @ThreadLock(busType = "拆分商品")
    public RestResult excelImportForDataSplit(@RequestParam(value = "file") MultipartFile file, @RequestParam Map<String, String> reqData) {
        try {
            return  RestResult.ok(service.excelImportForDataSplit(file,reqData));
        }catch (Exception e) {
            return  RestResult.error(e.getMessage());
        }
    }


    /**
     * @description: 导入商品 下载导入模板
     **/
    @GetMapping("/excelDownloadTempForDataImport")
    public void excelDownloadTempForDataImport(HttpServletResponse response, @RequestParam Map<String, String> reqData) {
        service.excelDownloadTemp(response,reqData, ExcelImportBaseDataConfig.getMatrDataImport());
    }

    /**
     * @description: 导入商品 导入数据
     **/
    @RequestMapping(value = "/excelImportForDataImport", method = RequestMethod.POST)
    @ThreadLock(busType = "导入商品")
    public RestResult excelImportForDataImport(@RequestParam(value = "file") MultipartFile file, @RequestParam Map<String, String> reqData) {
        try {
            return  service.excelImportForDataImport(file,reqData);
        }catch (Exception e) {
            logger.error("excelImportForDataImport.error",e);
            return  RestResult.error(e.getMessage());
        }
    }

    /**
     * 获取数据列表
     */
    @GetMapping("/pageWithReq")
    public PageResult pageWithReq(@RequestParam Map<String, String> reqData) {
        Map<String, Object> userParam = null;
        String queryType = "";
        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
            queryType = userParam.get("queryType") +"";
        }

        QueryContext queryContext = QueryContextHolder.currentContext();
        if ("useIn".equals(queryType)) {
            queryContext.getWrapper().apply(" ((base_type != '"+GlobalConsts.MATR_BASE_TYPE_LOM+"' and (flag_disabled_sp = 0  and flag_disabled = 0 and his_disabled = 0  and hrp_finance_disabled =0   and hrp_disabled =0 )) " +
                    " or (base_type = '"+GlobalConsts.MATR_BASE_TYPE_LOM+"' and (flag_disabled = 0 )))");
        }

        IPage pageResult = service.page(queryContext);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }
}
